package dcc.manager.base;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.text.JTextComponent;

import com.l2fprod.common.swing.JLinkButton;

import dcc.component.CustomComboBox;
import dcc.component.CustomTextField;
import dcc.component.PhotoPanel;
import dcc.mbg.model.BaseInfo;
import dcc.service.CommonService;
import dcc.tools.BeanFactory;
import dcc.tools.Tools;
import dcc.ui.MainWindow;

public abstract class InformationManager extends Manager {

	private JPanel centerPanel;
	private JTabbedPane tabbedPane;

	protected JTextField tfxingMing;
	protected JTextField tfshiBieHao;
	protected JTextField tfxingBie;
	protected JTextField tfleiBie;
	protected PhotoPanel zhaoPian;
	protected JButton btnSelectPhoto;
	protected int hiid;

	public InformationManager() {
		super();
		init();
	}

	private void init() {
		tfleiBie = new CustomTextField();
		tfleiBie.setEditable(false);
		resetLeiBie(tfleiBie);

		workPanel.setLayout(new BorderLayout(0, 0));
		JPanel topPanel = new JPanel();
		topPanel.setPreferredSize(new Dimension(10, 48));
		workPanel.add(topPanel, BorderLayout.NORTH);
		GridBagLayout gbl_topPanel = new GridBagLayout();
		gbl_topPanel.columnWidths = new int[] { 96, 96, 96, 96, 0 };
		gbl_topPanel.rowHeights = new int[] { 48, 0 };
		gbl_topPanel.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0,
				Double.MIN_VALUE };
		gbl_topPanel.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
		topPanel.setLayout(gbl_topPanel);

		JLinkButton lbtnAdd = new JLinkButton();
		lbtnAdd.setIcon(new ImageIcon(MainWindow.class
				.getResource("/dcc/resources/images/add.png")));
		lbtnAdd.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
		lbtnAdd.setText(Tools.get().getValue("LABEL_ADD"));
		lbtnAdd.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent me) {
				add();
			}
		});
		GridBagConstraints gbc_lbtnAdd = new GridBagConstraints();
		gbc_lbtnAdd.fill = GridBagConstraints.BOTH;
		gbc_lbtnAdd.insets = new Insets(0, 0, 0, 5);
		gbc_lbtnAdd.gridx = 0;
		gbc_lbtnAdd.gridy = 0;
		topPanel.add(lbtnAdd, gbc_lbtnAdd);

		JLinkButton lbtnSave = new JLinkButton();
		lbtnSave.setIcon(new ImageIcon(MainWindow.class
				.getResource("/dcc/resources/images/save.png")));
		lbtnSave.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
		lbtnSave.setText(Tools.get().getValue("LABEL_SAVE"));
		lbtnSave.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent me) {
				try {
					if (save() != 0) {
						JOptionPane.showMessageDialog(null, Tools.get()
								.getValue("LABEL_SAVE_OK_PROMPT"), Tools.get()
								.getValue("LABEL_PROMPT_TITLE"),
								JOptionPane.INFORMATION_MESSAGE);
					}
				} catch (Exception e) {
					String shiBieHao = tfshiBieHao.getText().trim();
					deletePic(shiBieHao, System.getProperty("user.dir")
							+ "\\photos\\" + shiBieHao + ".jpg");
					JOptionPane.showMessageDialog(null,
							Tools.get().getValue("LABEL_SAVE_ERROR_PROMPT"),
							Tools.get().getValue("LABEL_PROMPT_TITLE"),
							JOptionPane.INFORMATION_MESSAGE);
					e.printStackTrace();
				}
			}
		});
		GridBagConstraints gbc_lbtnSave = new GridBagConstraints();
		gbc_lbtnSave.fill = GridBagConstraints.BOTH;
		gbc_lbtnSave.insets = new Insets(0, 0, 0, 5);
		gbc_lbtnSave.gridx = 1;
		gbc_lbtnSave.gridy = 0;
		topPanel.add(lbtnSave, gbc_lbtnSave);

		JLinkButton lbtnFind = new JLinkButton();
		lbtnFind.setIcon(new ImageIcon(MainWindow.class
				.getResource("/dcc/resources/images/find.png")));
		lbtnFind.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
		lbtnFind.setText(Tools.get().getValue("LABEL_SELECT"));
		lbtnFind.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent me) {
				find();
			}
		});
		GridBagConstraints gbc_lbtnFind = new GridBagConstraints();
		gbc_lbtnFind.fill = GridBagConstraints.BOTH;
		gbc_lbtnFind.insets = new Insets(0, 0, 0, 5);
		gbc_lbtnFind.gridx = 2;
		gbc_lbtnFind.gridy = 0;
		topPanel.add(lbtnFind, gbc_lbtnFind);

		JLinkButton lbtnDelete = new JLinkButton();
		lbtnDelete.setIcon(new ImageIcon(MainWindow.class
				.getResource("/dcc/resources/images/delete.png")));
		lbtnDelete.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
		lbtnDelete.setText(Tools.get().getValue("LABEL_DELETE"));
		lbtnDelete.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent me) {
				delete();
			}
		});
		GridBagConstraints gbc_lbtnDelete = new GridBagConstraints();
		gbc_lbtnDelete.fill = GridBagConstraints.BOTH;
		gbc_lbtnDelete.gridx = 3;
		gbc_lbtnDelete.gridy = 0;
		topPanel.add(lbtnDelete, gbc_lbtnDelete);

		centerPanel = new JPanel();
		workPanel.add(centerPanel, BorderLayout.CENTER);
		centerPanel.setLayout(new BorderLayout(0, 0));

		setTabbedPane();
	}

	private void setTabbedPane() {
		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setFont(new Font("Microsoft YaHei", Font.PLAIN, 16));
		tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		tabbedPane.setDoubleBuffered(true);
		workPanel.add(tabbedPane, BorderLayout.CENTER);
	}

	protected void addTab(String title, JPanel panel) {
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setDoubleBuffered(true);
		tabbedPane.addTab(title, null, scrollPane, null);
		panel.setBackground(Color.WHITE);
		panel.setBorder(new EmptyBorder(0, 0, 0, 0));
		scrollPane.setViewportView(panel);
	}

	private void resetTextComponent(JComponent... panels) {
		for (JComponent panel : panels) {
			Component[] components = panel.getComponents();
			for (Component component : components) {
				if (component instanceof JTextComponent) {
					JTextComponent tmpComponent = (JTextComponent) component;
					tmpComponent.setText("");
				}
			}
		}
	}

	private void resetLeiBie(JTextField textField) {
		String typeName = this.getClass().getName();
		textField.setText(Tools.get().getValue(
				"TYPE_" + typeName.substring(typeName.lastIndexOf(".") + 1)));
	}

	public void add() {
		this.zhaoPian.clearImage();
	}

	protected BaseInfo prepareBaseInfo() {
		if ("".equals(this.tfshiBieHao.getText())
				|| "".equals(this.tfxingMing.getText())
				|| "".equals(this.tfleiBie.getText())) {
			JOptionPane.showMessageDialog(null,
					Tools.get().getValue("LABEL_SAVE_PROMPT"), Tools.get()
							.getValue("LABEL_PROMPT_TITLE"),
					JOptionPane.INFORMATION_MESSAGE);
			return null;
		} else {
			BaseInfo baseInfo = (BaseInfo) setModelField(BaseInfo.class,
					InformationManager.class);
			if (baseInfo != null) {
				// TODO copy photo to photos directory
				baseInfo.setZhaoPian(this.zhaoPian
						.savePhotoFileToAppPath(baseInfo.getShiBieHao()));
			}
			BaseInfo existingRecord = ((CommonService) BeanFactory
					.getBean("commonService"))
					.getBaseInfoByShiBieHaoAndLeiBie(baseInfo);
			if (existingRecord != null) {
				if (JOptionPane.OK_OPTION != JOptionPane.showConfirmDialog(
						null, Tools.get().getValue("LABEL_UPDATE_PROMPT"),
						Tools.get().getValue("LABEL_PROMPT_TITLE"),
						JOptionPane.OK_CANCEL_OPTION)) {
					return null;
				} else {
					baseInfo.setId(existingRecord.getId());
				}
			}
			return baseInfo;
		}
	}

	// protected int save() {
	// if ("".equals(this.tfRCSBH.getText()) ||
	// "".equals(this.tfXM.getText())
	// || "".equals(this.tfRCLB.getText())) {
	// JOptionPane.showMessageDialog(null,
	// Tools.get().getValue("LABEL_SAVE_PROMPT"), Tools.get()
	// .getValue("LABEL_PROMPT_TITLE"),
	// JOptionPane.INFORMATION_MESSAGE);
	// return 0;
	// }
	// BaseInfo baseInfo = (BaseInfo) setModelField(BaseInfo.class,
	// InformationManager.class);
	// BaseInfo existingRecord = ((BaseInfoService) BeanFactory
	// .getBean("baseInfoService"))
	// .getBaseInfoBySBHAndLB(baseInfo);
	// if (existingRecord != null) {
	// if (JOptionPane.CANCEL_OPTION == JOptionPane.showConfirmDialog(
	// null, Tools.get().getValue("LABEL_UPDATE_PROMPT"), Tools
	// .get().getValue("LABEL_PROMPT_TITLE"),
	// JOptionPane.OK_CANCEL_OPTION)) {
	// return 0;
	// } else {
	// baseInfo.setId(existingRecord.getId());
	// }
	// }
	// TODO copy photo to photos directory
	// baseInfo.setZhaoPian(this.zhaoPian.savePhotoFileToAppPath(baseInfo
	// .getShiBieHao()));
	// TODO Save info to DB return newId
	// ((BaseInfoService) BeanFactory.getBean("baseInfoService"))
	// .save(baseInfo);
	// return baseInfo.getId();
	// }

	protected abstract int save() throws Exception;

	protected Object setModelField(Class<?> modelClass, Class<?> managerClass) {
		Object model = null;
		try {
			Field[] fields = managerClass.getDeclaredFields();
			String fieldName;
			String methodName;
			model = modelClass.getConstructor().newInstance();
			for (Field field : fields) {
				fieldName = field.getName();
				if (fieldName.startsWith("tf") || fieldName.startsWith("cb")
						|| fieldName.startsWith("hi")) {
					fieldName = fieldName.substring(2, 3).toUpperCase()
							+ fieldName.substring(3);
					methodName = "set" + fieldName;
					try {
						if (field.getName().equals("hiid")) {
							if (field.getInt(this) != 0) {
								Method setMethod = modelClass
										.getDeclaredMethod(methodName,
												Integer.class);
								setMethod.invoke(model, field.getInt(this));
							} else {
								continue;
							}
						} else {
							Method setMethod = modelClass.getDeclaredMethod(
									methodName, String.class);
							if (field.getType() == CustomComboBox.class) {
								setMethod.invoke(model, ""
										+ ((CustomComboBox) field.get(this))
												.getSelectedItem().toString());
							} else {
								setMethod.invoke(model, ""
										+ ((JTextComponent) field.get(this))
												.getText().trim());
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return model;
	}

	public void bindModel(BaseInfo baseInfo) {
		this.getModelField(baseInfo, InformationManager.class);
		if (baseInfo.getZhaoPian() != null
				&& !"".equals(baseInfo.getZhaoPian())) {
			this.zhaoPian.loadPhotoFromAppPath(baseInfo.getZhaoPian());
		}
	}

	protected void getModelField(Object model, Class<?> managerClass) {
		try {
			Field[] fields = managerClass.getDeclaredFields();
			String fieldName;
			String methodName;
			for (Field field : fields) {
				fieldName = field.getName();
				if (fieldName.startsWith("tf") || fieldName.startsWith("cb")) {
					fieldName = fieldName.substring(2, 3).toUpperCase()
							+ fieldName.substring(3);
					methodName = "get" + fieldName;
					try {
						System.out.println(methodName);
						Method getMethod = model.getClass().getDeclaredMethod(
								methodName);
						if (field.getType() == CustomComboBox.class) {
							((CustomComboBox) field.get(this)).setText(""
									+ getMethod.invoke(model));
						} else {
							((JTextComponent) field.get(this)).setText(""
									+ getMethod.invoke(model));
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void find() {
		// TODO Show search Window
		Tools.get().getSearchWindow().setVisible(true);
		Tools.get().getSearchWindow().setExtendedState(Frame.NORMAL);
	}

	public void delete() {
		if ("".equals(this.tfshiBieHao.getText())
				|| "".equals(this.tfleiBie.getText())) {
			JOptionPane.showMessageDialog(null,
					Tools.get().getValue("LABEL_DELETE_PROMPT"), Tools.get()
							.getValue("LABEL_PROMPT_TITLE"),
					JOptionPane.INFORMATION_MESSAGE);
			return;
		}
		BaseInfo baseInfo = (BaseInfo) setModelField(BaseInfo.class,
				InformationManager.class);
		// TODO Delete from DB
		// ((BaseInfoService) BeanFactory.getBean("baseInfoService"))
		// .deleteBaseInfoBySBHAndLB(baseInfo);
		int result = ((CommonService) BeanFactory.getBean("commonService"))
				.deleteBaseInfoByShiBieHaoAndLeiBie(baseInfo);
		if (result != 0) {
			deletePic(baseInfo.getShiBieHao(), System.getProperty("user.dir")
					+ "\\photos\\" + baseInfo.getShiBieHao() + ".jpg");
			// this.add();
		}
	}

	private void deletePic(String shiBieHao, String picName) {
		// TODO Check DB the shiBieHao is exists ?
		boolean isExist = ((CommonService) BeanFactory.getBean("commonService"))
				.isExistsByShiBieHao(shiBieHao);
		if (!isExist) {
			if (picName != null && !picName.equals("")) {
				File f = new File(picName);
				if (f.exists()) {
					f.delete();
				}
			}
		}
	}
}